package com.jml.curator.task.service;


import com.jml.curator.task.config.CuratorZkLock;
import com.jml.curator.task.entity.CommodityDetails;
import com.jml.curator.task.mapper.CommodityDetailsMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@Slf4j
public class SeckillService {
    @Autowired
    private CuratorZkLock curatorZkLock;
    // ZooKeeper 锁节点路径, 分布式锁的相关操作都是在这个节点上进行
    private final String lockPath = "/distributed-lock";
    @Autowired
    private CommodityDetailsMapper commodityDetailsMapper;

    /**
     * 秒杀lock
     * @return
     */
    @RequestMapping("/seckilLock")
    public String seckilLock() throws Exception {
        InterProcessMutex interProcessMutex = null;
        try {
            CuratorFramework client = curatorZkLock.getClient();
            // 获取锁 底层:zk上创建一个临时顺序编号节点
            interProcessMutex = new InterProcessMutex(client, lockPath);
            //获取锁 一直没有获取锁成功的情况下，默认是会阻塞。
            interProcessMutex.acquire();
            log.info("<获取锁成功....>");
            CommodityDetails commodityDetails = commodityDetailsMapper.getCommodityDetails(1L);
            Long stock = commodityDetails.getStock();
            if (stock > 0) {
                log.info("<开始执行扣库存..>");
                int result = commodityDetailsMapper.reduceInventory(1L);
                return result > 0 ? "扣库存成功" : "扣库存失败";
            }
            // 扣库存失败s
            log.info("<扣库存失败>");
            return "fail";

        } catch (Exception e) {
            e.printStackTrace();
            log.info("<秒杀出现错误:e:{}>", e);
            return "fail";
        } finally {
            // 释放锁
            if (interProcessMutex != null) {
                interProcessMutex.release();
                log.info("<清楚锁成功....>");
            }
        }
    }
}
